home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / pxewin.zip / BROWSER.CPP < prev    next >
C/C++ Source or Header  |  1992-01-17  |  27KB  |  1,097 lines

  1. // BROWSER_HPP //
  2.  
  3. // Contents ----------------------------------------------------------------
  4. //
  5. //    This header contains members for the following classes and
  6. //    structures:
  7. //
  8. //    1.  Class PXListBox.  Redefines listboxes for browsing PDOX tables.
  9. //
  10. //    2.  Stucture LB_PARM.  Stores the parameters for all the list boxes.
  11. //
  12. //    3.  Class DBDISPLAY.  Displays the database in page format with 20
  13. //    records per page.
  14. //
  15. //    4.  Class PXScroller.  Redifines the scroller for scrolling PDOX
  16. //    tables.  The vertical scroll is all that is redefined.
  17. //
  18. //    5.  Class Browser.  Creates a browser window that is MDI complient.
  19. //
  20. //    6.  Class BrowserFrame.  Creates a MDI frame for creating browser
  21. //    windows.
  22. //
  23. // End ---------------------------------------------------------------------
  24.  
  25. // External Reference Name For This Header ---------------------------------
  26.  
  27. #ifndef BROWSER_CPP
  28.     #define BROWSER_CPP
  29.  
  30. // End ---------------------------------------------------------------------
  31.  
  32. // Interface Dependencies --------------------------------------------------
  33.  
  34. #ifndef BROWSER_HPP
  35.     #include "browser.hpp"
  36. #endif
  37.  
  38. // member VScroll of PXScroller //
  39.  
  40. void PXScroller::VScroll(WORD ScrollEvent,int ThumbPos)
  41. {
  42.     // In case the number of records changes.
  43.  
  44.     my_display->my_table->NumRecs();
  45.     SetRange(my_display->RetSum(),
  46.         my_display->EngDataPtr->num_recs - 1);
  47.  
  48.     switch(ScrollEvent)
  49.     {
  50.         case SB_LINEDOWN:
  51.         {
  52.             YPos++;
  53.             my_display->IncRec();
  54.             break;
  55.         }
  56.         case SB_LINEUP:
  57.         {
  58.             YPos--;
  59.             my_display->DecRec();
  60.             break;
  61.         }
  62.         case SB_THUMBPOSITION:
  63.         {
  64.             YPos = ThumbPos;
  65.             my_display->FillBoxes(YPos + 1);
  66.             break;
  67.         }
  68.         case SB_PAGEDOWN:
  69.         {
  70.             YPos += PAGE_SIZE;
  71.             my_display->FillBoxes(YPos + 1);
  72.             break;
  73.         }
  74.         case SB_PAGEUP:
  75.         {
  76.             YPos -= PAGE_SIZE;
  77.             my_display->FillBoxes(YPos + 1);
  78.             break;
  79.         }
  80.     }
  81.  
  82.     // Scroll bars should reflect current database position.
  83.  
  84.     YPos = my_display->RetCurRec() - 1;
  85.  
  86.     // EndView will set the scroller to the desired position
  87.  
  88.     EndView();
  89. }
  90.  
  91. // Summary -----------------------------------------------------------------
  92. //
  93. //    Redefine vertical scroll bars to allow scrolling through a table.
  94. //
  95. // Parameters
  96. //
  97. //    ScrollEvent.  This is the scroll event parameters.
  98. //
  99. //    Thumbpos.  The thumb position of the scroll bar.
  100. //
  101. // Return Value
  102. //
  103. //    None.
  104. //
  105. // Functional Description
  106. //
  107. //    Each vertical scroll event is redefined here.  Each increment of
  108. //    YPos cooresponds to one record in the database.  First check and
  109. //    make sure the range is set according to the number of records in
  110. //    the table.
  111. //
  112. //    The following is a summary of the scrolling events and how they are
  113. //    handled:
  114. //
  115. //    SB_LINEDOWN.  Increment YPos.  Call your display increment
  116. //    record routine.
  117. //
  118. //    SB_LINEUP.  Decrement YPos.  Call your display decrement record
  119. //    routine.
  120. //
  121. //    SB_THUMBPOSITION.  Set YPos to thumb position.  Call your display
  122. //    routine for filling the boxes.  Record position starts with record
  123. //    1 so you have to add 1 to the YPos to get the record number.
  124. //
  125. //      SB_PAGEDOWN.  Add the page size to YPos.  Call your display routine
  126. //    for filling the boxes.
  127. //
  128. //    SB_PAGEUP.  Subtract the page size from YPos.  Call you display
  129. //    routine for filling the boxes.
  130. //
  131. //
  132. //    You will notice that we have not done any range checks on YPos.
  133. //    Range checking is done in the display routine.  So we call the
  134. //    display routine to give us the current record for YPos.  This will
  135. //    be range checked.  Then we can call EndView to set the final scroll
  136. //    position.
  137. //
  138. // End ---------------------------------------------------------------------
  139.  
  140. // constructor DBDISPLAY //
  141.  
  142. inline DBDISPLAY::DBDISPLAY()
  143. {
  144.     my_parm = NULL;
  145.     UpdateFlag = 1;
  146.  
  147. }
  148.  
  149. // Description -------------------------------------------------------------
  150. //
  151. //    Constructor for DBDISPLAY.  Set my_parm to NULL, UpdateFlag for
  152. //    display updates and create a new windows class object.
  153. //
  154. // End ---------------------------------------------------------------------
  155.  
  156. // Description -------------------------------------------------------------
  157. //
  158. //    Sets cursor to normal type cursor.
  159. //
  160. // End ---------------------------------------------------------------------
  161.  
  162. // member FillBoxes //
  163.  
  164. void DBDISPLAY::FillBoxes(RECORDNUMBER rec)
  165. {
  166.     int i;                    /* Field index */
  167.     int j;                    /* Record index */
  168.     int sel;                /* Temperary item selection
  169.                            variable */
  170.     int upper_limit;            /* Number of records to
  171.                            get */
  172.     char* temp;
  173.  
  174.     // Set mouse cursor to wait
  175.  
  176.     SendMessage(AP->Parent->HWindow,WM_SETWTCUR,0,0);
  177.  
  178.     // Reset update flag
  179.  
  180.     UpdateFlag = 0;
  181.  
  182.     // Check and see if record number is less than first record.
  183.  
  184.     if(rec < 1)
  185.         rec = 1;
  186.  
  187.     // Get the number of records in the table.
  188.  
  189.     my_table->NumRecs();
  190.  
  191.     // If you have less records then a PAGE_SIZE, then set your first
  192.     // record of the page to the first record in the database.  Set the
  193.     // upper limit of the last record you will get to the number of
  194.     // records in the database.
  195.  
  196.     if(EngDataPtr->num_recs < PAGE_SIZE)
  197.     {
  198.         upper_limit = EngDataPtr->num_recs;
  199.         top_rec = 1;
  200.     }
  201.     else
  202.     {
  203.  
  204.         // Else, set the upper limit to the page size.
  205.  
  206.         upper_limit = PAGE_SIZE;
  207.  
  208.         // If you are less than a page size away from the end of the
  209.         // database, set the top record to the number of records in
  210.         // the database minus the size of the page.
  211.  
  212.         if(rec + PAGE_SIZE > EngDataPtr->num_recs){
  213.             top_rec = EngDataPtr->num_recs - PAGE_SIZE + 1;
  214.             sel = rec - top_rec;
  215.         }
  216.         else
  217.         {
  218.  
  219.             // Else, leave the top record value at the parameter
  220.             // setting.
  221.  
  222.             top_rec = rec;
  223.             sel = 0;
  224.         }
  225.     }
  226.  
  227.     // Empty the list boxes.
  228.  
  229.     for(i = 0;i < EngDataPtr->num_fields;i++)
  230.         my_parm[i]->my_box->ClearList();
  231.  
  232.     my_record->GoTo(top_rec);
  233.     for(j = 0;j < upper_limit;j++)
  234.     {
  235.  
  236.         // Get the record data into the record transfer buffer.
  237.  
  238.         my_record->Get();
  239.         for(i = 0;i < EngDataPtr->num_fields;i++)
  240.         {
  241.  
  242.             // Get the field data and put in into the list box.
  243.  
  244.             temp = PXDIS::Get(i);
  245.             my_parm[i]->my_box->AddString(temp);
  246.         }
  247.  
  248.         // Go to the next record.
  249.  
  250.         my_record->RecNext();
  251.     }
  252.  
  253.     // Set item out of bounds so it will pass through range check ok
  254.  
  255.     item = -1;
  256.  
  257.     // Set update flag
  258.  
  259.     UpdateFlag = 1;
  260.  
  261.     // Select the item
  262.  
  263.     SelRecord(sel);
  264.  
  265.     // Set mouse cursor to normal
  266.  
  267.     SendMessage(AP->Parent->HWindow,WM_SETNMCUR,0,0);
  268. }
  269.  
  270. // Summary -----------------------------------------------------------------
  271. //
  272. //    This member fills the list boxes with data from the database.
  273. //
  274. // Parameters
  275. //
  276. //    rec.  This is the record number of the top record in the list boxes.
  277. //
  278. // Return Value
  279. //
  280. //    None.
  281. //
  282. // Functional Description
  283. //
  284. //    1.  Set the mouse cursor to the wait cursor.
  285. //
  286. //    2.  Reset the UpdateFlag so updates will not occur until the list
  287. //    boxes are refilled.  This flag will be read by the PXListBox
  288. //    routine to make sure Updates as they would normally when WMPaint is
  289. //    called (TControl version of WMPaint).
  290. //
  291. //    3.  Range check rec.  If it is less than the first record, reset it
  292. //    to the first record.  For a table that is less the a PAGE_SIZE, limit
  293. //    the upperbound accordingly.  Else the upperbound is the PAGE_SIZE.
  294. //      If rec plus PAGE_SIZE is greater than the number of records then set
  295. //    top_rec to PAGE_SIZE less than the number of records and your
  296. //    selection is somewhere in between.  Else leave rec untouched and
  297. //    set you selection to the top record.
  298. //
  299. //    4.  Empty the list boxes.
  300. //
  301. //    5.  Fill the list boxes.
  302. //
  303. //    6.  You need to set the item number out of bounds so the selection
  304. //    routine sees that the selection has changed.
  305. //
  306. //    7.  Set the UpdateFlag to allow updates and call the selection
  307. //    routine.
  308. //
  309. //    8.  Set the mouse cursor to normal.
  310. //
  311. // End ---------------------------------------------------------------------
  312.  
  313. // member SetUp //
  314.  
  315. int DBDISPLAY::SetUp(Browser *AParent)
  316. {
  317.     char *header;                /* Temp location for header
  318.                         */
  319.     int hd_len;                /* Length of header */
  320.     int char_size;                /* Is the number of ASCII
  321.                            characters it takes to
  322.                            represent the field. */
  323.     int i;                    /* Field index */
  324.  
  325.     item = -1;                /* Set item pointer to a
  326.                            nonselected location */
  327.  
  328.     EngDataPtr->name = AParent->name;
  329.     AP = AParent;
  330.     sum = 1;
  331.  
  332.     // Setup database
  333.  
  334.     PXDIS::SetUp(0,0,EXISTS,0);
  335.  
  336.     // Make an array of field parameter pointers
  337.  
  338.     my_parm = new LB_PARM* [EngDataPtr->num_fields];
  339.  
  340.     for(i = 0;i < EngDataPtr->num_fields;i++){
  341.         my_parm[i] = new LB_PARM;
  342.  
  343.         // Set up a field pointer
  344.  
  345.         my_parm[i]->my_field = my_field[i];
  346.  
  347.         // If parameter set is the first set, initialize x
  348.         // coordinate of the list box independently.
  349.  
  350.         if(i == 0)
  351.             my_parm[i]->x = 2;
  352.         else{
  353.  
  354.             // Else, the list box coordinate depends on
  355.             // where the previous list box ends.
  356.  
  357.             my_parm[i]->x = my_parm[i - 1]->x +
  358.                 my_parm[i - 1]->w + 2;
  359.         }
  360.  
  361.         // Precalc some things we will be using more than once.
  362.  
  363.         header = my_parm[i]->my_field->RetName();
  364.         hd_len = strlen(header);
  365.         char_size = my_parm[i]->my_field->RetCharSize();
  366.  
  367.         // The width of the list box is calculated.  It is
  368.         // the character size of the field times the
  369.         // character width unless the field header is larger.
  370.  
  371.         if(char_size > hd_len){
  372.             my_parm[i]->w = char_size*CHAR_WIDTH;
  373.             sum += char_size;
  374.         }
  375.         else{
  376.             my_parm[i]->w = hd_len*CHAR_WIDTH;
  377.             sum += hd_len;
  378.         }
  379.  
  380.         // Set up the list box.
  381.  
  382.         my_parm[i]->my_box = new PXListBox(AParent,i,
  383.             my_parm[i]->x,20,my_parm[i]->w,16.5*PAGE_SIZE);
  384.  
  385.         // Set up header for your list boxes
  386.  
  387.         my_parm[i]->my_header = new TStatic(AParent,-1,
  388.             header,my_parm[i]->x,1,200,15,hd_len + 1);
  389.  
  390.     }
  391.     return PXSUCCESS;
  392. }
  393.  
  394. // Summary -----------------------------------------------------------------
  395. //
  396. //    This sets up the database for displaying all the fields.
  397. //
  398. // Parameters
  399. //
  400. //      AParent.  Needs the parent window object to construct the list boxes
  401. //    and the field headers.
  402. //
  403. // Functional Description
  404. //
  405. //    1.  Call the SetUp routine for setting up the database.
  406. //
  407. //    2.  Construct a parameter array for storing list box info.
  408. //
  409. //    3.  Construct a for loop that will initialize all the fields for
  410. //    display.  The information necessary for storing the list box data is
  411. //    saved in the LB_PARM structure.  Placement locations and sizes of
  412. //    each list box are calculated.  Headers for each field are placed
  413. //    at the top of the list box.
  414. //
  415. // End ---------------------------------------------------------------------
  416.  
  417. // Destructor ~DBDISPLAY //
  418.  
  419. DBDISPLAY::~DBDISPLAY()
  420. {
  421.     int i;                    /* Field index */
  422.  
  423.     // if ther is no parameter pointer, then the number of fields is
  424.     // unknown so set to zero.
  425.  
  426.     if(!my_parm)
  427.         EngDataPtr->num_fields = 0;
  428.     for(i = 0;i < EngDataPtr->num_fields;i++)
  429.         delete my_parm[i];
  430.     delete my_parm;
  431. }
  432.  
  433. // End ---------------------------------------------------------------------
  434.  
  435. // Summary -----------------------------------------------------------------
  436. //
  437. //    Kills all buffers used in DBDISPLAY.
  438. //
  439. // End ---------------------------------------------------------------------
  440.  
  441. // member SelRecord //
  442.  
  443. void DBDISPLAY::SelRecord(int ITEM)
  444. {
  445.     int i;                    /* Field index */
  446.  
  447.     // Range check item
  448.  
  449.     if(ITEM >= PAGE_SIZE)
  450.         ITEM = PAGE_SIZE - 1;
  451.     if(ITEM < 0)
  452.         ITEM = 0;
  453.     if(item == ITEM)
  454.     {
  455.         if(item == 0)
  456.             ScrollDwn();
  457.         else{
  458.             if(item == PAGE_SIZE - 1)
  459.                 ScrollUp();
  460.         }
  461.     }
  462.  
  463.     // Select items if you are somewhere within a page or your have
  464.     // incremented past the page but you are not at the last record.
  465.     // For a decrement before the page you don't need to select since
  466.     // you are doing and insert at the first record.
  467.  
  468.     if((item == PAGE_SIZE - 1) || item != ITEM)
  469.     {
  470.         for(i = 0;i < EngDataPtr->num_fields;i++)
  471.         {
  472.             my_parm[i]->my_box->SetSelIndex(ITEM);
  473.         }
  474.     }
  475.     item = ITEM;
  476. }
  477.  
  478. // Summary -----------------------------------------------------------------
  479. //
  480. //      Selects the record cooresponding to the item number in the list boxes
  481. //
  482. // Parameters
  483. //
  484. //    item.  This is the list box item number.
  485. //
  486. // Return Value
  487. //
  488. //    None.
  489. //
  490. // Description
  491. //
  492. //      1.  The item number is range checked.  If the item number is greater
  493. //    then the page size then it is set to the page size.  If the item
  494. //    number is less than the first item number, it is set to the first
  495. //    item.
  496. //
  497. //    2.  If the old item number is equal to the new item number then check
  498. //    for a scroll up or down situation.  It is scroll up if item is the
  499. //    first item, scroll down if item is the last item in the list box.
  500. //
  501. //    3.  If item selected is at the end of the list or somewhere in
  502. //    the middle of the list, then set all the lists to the same item.
  503. //
  504. // End ---------------------------------------------------------------------
  505.  
  506. // member IncRec of DBDISPLAY //
  507.  
  508. void DBDISPLAY::IncRec()
  509. {
  510.     SelRecord(item + 1);
  511. }
  512.  
  513. // Summary -----------------------------------------------------------------
  514. //
  515. //    Increments an item in the list boxes.
  516. //
  517. // End ---------------------------------------------------------------------
  518.  
  519. // member DecRec of DBDISPLAY //
  520.  
  521. void DBDISPLAY::DecRec()
  522. {
  523.     SelRecord(item - 1);
  524. }
  525.  
  526. // Summary -----------------------------------------------------------------
  527. //
  528. //    Decrements an item in the list boxes.
  529. //
  530. // End ---------------------------------------------------------------------
  531.  
  532.  
  533. // member ScrollUp //
  534.  
  535. void DBDISPLAY::ScrollUp()
  536. {
  537.     int i;                    /* Field index */
  538.  
  539.     // Make sure your not already at the last record in the table.
  540.     // Note that we specifically call for the number of records since
  541.     // this may change as we add and delete records from the database.
  542.  
  543.     my_table->NumRecs();
  544.     if(top_rec + PAGE_SIZE <= EngDataPtr->num_recs){
  545.  
  546.         // Go to the new record and get data
  547.  
  548.         my_record->GoTo(top_rec + PAGE_SIZE);
  549.         my_record->Get();
  550.  
  551.         for(i = 0;i < EngDataPtr->num_fields;i++)
  552.         {
  553.             // Delete the first item in the list
  554.  
  555.             my_parm[i]->my_box->DeleteString(0);
  556.  
  557.             // Add the new next item to the list
  558.  
  559.             my_parm[i]->my_box->AddString(PXDIS::Get(i));
  560.         }
  561.         top_rec++;
  562.     }
  563. }
  564.  
  565. // Summary -----------------------------------------------------------------
  566. //
  567. //    This scrolls the display up by one record.
  568. //
  569. // Parameters
  570. //
  571. //    None.
  572. //
  573. // Return Value
  574. //
  575. //    None.
  576. //
  577. // Description
  578. //
  579. //      1.  Do a boundary check and make sure your not at the last record.
  580. //
  581. //    2.  Go to the last record in the list and get the data.
  582. //
  583. //    3.  For all the lists, delete the first item in the list and add the
  584. //      new data to the end of the list.
  585. //
  586. //    4.  Increment the top record pointer.
  587. //
  588. // End ---------------------------------------------------------------------
  589.  
  590. // member ScrollDwn //
  591.  
  592. void DBDISPLAY::ScrollDwn()
  593. {
  594.     int i;                    /* Field index */
  595.  
  596.     // Make sure your not already at the first record in the table
  597.  
  598.     if(top_rec > 1){
  599.  
  600.         // Go to the new record and get data
  601.  
  602.         top_rec--;
  603.         my_record->GoTo(top_rec);
  604.         my_record->Get();
  605.  
  606.         for(i = 0;i < EngDataPtr->num_fields;i++)
  607.         {
  608.             // Delete the last item in the list
  609.  
  610.             my_parm[i]->my_box->DeleteString(PAGE_SIZE - 1);
  611.  
  612.             // Add the new text item to the begining of the list
  613.  
  614.             my_parm[i]->my_box->InsertString(PXDIS::Get(i),0);
  615.         }
  616.     }
  617. }
  618.  
  619. // Summary -----------------------------------------------------------------
  620. //
  621. //    Scrolls the display down one record.
  622. //
  623. // Parameters
  624. //
  625. //    None.
  626. //
  627. // Return Value
  628. //
  629. //    None.
  630. //
  631. // Description
  632. //
  633. //      1.  Make sure you are not at the first record in the database.
  634. //
  635. //    2.  Decrement the top record pointer.
  636. //
  637. //    3.  Go to the top record and get the data.
  638. //
  639. //    4.  For all the fields, delete the last string in the list and insert
  640. //    the new data at the first string position in the list.
  641. //
  642. // End ---------------------------------------------------------------------
  643.  
  644. // member Browser //
  645.  
  646. Browser::Browser(PTWindowsObject AParent,int):TWindow(AParent,"")
  647. {
  648.     // Create a new DBDISPLAY
  649.  
  650.     name = new char[MAXPATH];
  651.     my_display = new DBDISPLAY;
  652.     strcpy(name,"*.db");            /* Construct a file mask for
  653.                            the file dialog */
  654.     // Execute file dialog
  655.  
  656.     if(GetApplication()->ExecDialog(
  657.         new TFileDialog(this,SD_FILEOPEN,
  658.         name)) == IDOK)
  659.     {
  660.         flag = EXISTS;
  661.  
  662.         // Store a copy of the database name to the window header
  663.  
  664.         Title = _fstrdup(name);
  665.         if(*Title == NULL)
  666.             flag = NOTEXISTS;
  667.     }
  668.     else
  669.         flag = NOTEXISTS;
  670.  
  671.     // If database does not exist, NULL out db and return
  672.  
  673.     if(flag == NOTEXISTS)
  674.         return;
  675.     flag = EXISTS;
  676.  
  677.     // Get the display for the database setup.
  678.  
  679.     my_display->SetUp(this);
  680.     if(my_display->RetPXError() != PXSUCCESS)
  681.     {
  682.         MessageBox(HWindow,
  683.         my_display->RetPXErrorMsg(),
  684.         "Database Error",MB_OK);
  685.         flag = NOTEXISTS;
  686.         return;
  687.     }
  688.  
  689.     // Set up scroll bars.
  690.  
  691.     Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  692.  
  693.     // Point the Scroller to the custom database scroller.  Vertical
  694.     // scroll will be redifined.
  695.  
  696.     Scroller = new PXScroller(this,8,15,80,60);
  697.  
  698. }
  699.  
  700. // Summary -----------------------------------------------------------------
  701. //
  702. //    Creates a browser window for browsing a Paradox database.
  703. //
  704. // Parameters
  705. //
  706. //      AParent.  This would be the MDI frame window.
  707. //
  708. //    The int is for the window count since each window object is put into
  709. //    a linked list.
  710. //
  711. // Functional Description
  712. //
  713. //      1.  Create a new name buffer for the database name.
  714. //
  715. //    2.  Call the File dialog box.  If file exists, set flag to EXISTS.
  716. //      Save a copy of the file name to the Title of the window data member.
  717. //    If the Title is NULL or the file dialog does not return IDOK then
  718. //    set existance flag to NOTEXIST.
  719. //
  720. //    3.  If flag is set to NOTEXIST, return to BrowserFrame.
  721. //
  722. //    4.  Set up the database.
  723. //
  724. //    5.  If an error occured in the set up, display the error, set the
  725. //    flag to NOTEXIST and return to the MDI.
  726. //
  727. //    6.  Set the styles for the scroll bars and construct the Scroller.
  728. //
  729. // End ---------------------------------------------------------------------
  730.  
  731. // destructor Browser //
  732.  
  733. inline Browser::~Browser()
  734. {
  735.     // Dispatch a message to the BrowserFrame that you have killed
  736.     // yourself.
  737.  
  738.     SendMessage(Parent->HWindow,WM_CHKCHILD,0,0);
  739. }
  740.  
  741. // Summary -----------------------------------------------------------------
  742. //
  743. //    Delete database name and tell the BrowserFrame to check its children.
  744. //
  745. // End ---------------------------------------------------------------------
  746.  
  747. // constructor PXListBox //
  748.  
  749. PXListBox::PXListBox(Browser *AParent,
  750.     int AnId,int X,int Y,int W,int H,
  751.     PTModule AModule):
  752.     TListBox((PTWindowsObject)AParent,
  753.     AnId,X,Y,W,H,AModule)
  754. {
  755.     // Copy display pointer
  756.  
  757.     my_display = AParent->my_display;
  758.  
  759.     // Disable item sort.
  760.  
  761.     Attr.Style &= ~LBS_SORT;
  762. }
  763.  
  764. // Summary -----------------------------------------------------------------
  765. //
  766. //    Redefines and sets up list boxes for the browser display.
  767. //
  768. // Parameters
  769. //
  770. //    Parameters are as they are ussually for list boxes except the
  771. //    parent window is of type Browser.  This must be caste to a
  772. //    PTWindowsObject type.
  773. //
  774. // Functional Description
  775. //
  776. //    Caste the parent window to my display object so we can call display
  777. //    routines.  Set the style so that the list boxes are not sorted.
  778. //
  779. // End ---------------------------------------------------------------------
  780.  
  781. void PXListBox::LBNSelChange(RTMessage)
  782. {
  783.     my_display->SelRecord(GetSelIndex());
  784. }
  785.  
  786.  
  787.  
  788. void PXListBox::WMPaint(RTMessage Msg)
  789. {
  790.     if(my_display->RetFlag())
  791.         TControl::WMPaint(Msg);
  792. }
  793.  
  794. // Description -------------------------------------------------------------
  795. //
  796. // Redefine WMPaint so that list boxes are not drawn when the
  797. // the Update flag is reset.  Since the OWL will do screen refresh
  798. // on the list boxes for each new entrie in the box, it is better
  799. // to do a paint after the list has completely been updated.
  800. //
  801. // End ---------------------------------------------------------------------
  802.  
  803. // member SetupWindow //
  804.  
  805. void Browser::SetupWindow()
  806. {
  807.     TWindow::SetupWindow();
  808.  
  809.     // You want to set the x scroller range depending on how many
  810.     // total characters you have in all the fields.  The y
  811.     // scroller range is determined by how many records you have
  812.     // in the database.
  813.  
  814.     my_display->my_table->NumRecs();
  815.     Scroller->SetRange(my_display->RetSum(),
  816.         my_display->EngDataPtr->num_recs - 1);
  817.  
  818.     // Get the data from the database and fill up list boxes
  819.     // with it and select the first entrie.
  820.  
  821.     my_display->FillBoxes(1);
  822. }
  823.  
  824. // Summary -----------------------------------------------------------------
  825. //
  826. //    Sets up browser window
  827. //
  828. // Parameters
  829. //
  830. //    None.
  831. //
  832. // Return Value
  833. //
  834. //    None.
  835. //
  836. // Description
  837. //
  838. //      Calls TWindows set up.  Sets the range on the scroll bar to
  839. //    conform with the database ranges and fills the list boxes with
  840. //    the data.
  841. //
  842. // End ---------------------------------------------------------------------
  843.  
  844. // member CursorWait of BrowserFrame //
  845.  
  846. inline void BrowserFrame::CursorWait(RTMessage)
  847. {
  848.     MyClass->hCursor = LoadCursor(NULL,IDC_WAIT);
  849.     SetCursor(MyClass->hCursor);
  850. }
  851.  
  852. // Description -------------------------------------------------------------
  853. //
  854. //    Sets cursor to wait type cursor.
  855. //
  856. // End ---------------------------------------------------------------------
  857.  
  858. // member CursorNormal of BrowserFrame //
  859.  
  860. inline void BrowserFrame::CursorNormal(RTMessage)
  861. {
  862.     MyClass->hCursor = LoadCursor(NULL,IDC_ARROW);
  863.     SetCursor(MyClass->hCursor);
  864. }
  865.  
  866. // member MenuItemDisable of BrowserFrame //
  867.  
  868. inline void BrowserFrame::MenuItemDisable(int item)
  869. {
  870.     HMENU hMenu;            /* Menu handle */
  871.  
  872.     // Get the menu handle
  873.  
  874.     hMenu = GetMenu(HWindow);
  875.  
  876.     // Disable menu item.
  877.  
  878.     EnableMenuItem(hMenu,item,MF_GRAYED);
  879. }
  880.  
  881. // Summary -----------------------------------------------------------------
  882. //
  883. //    Disables selected menu item.
  884. //
  885. // Parameter
  886. //
  887. //    item.  Is the menu item number to disable.
  888. //
  889. // End ---------------------------------------------------------------------
  890.  
  891. // member MenuItemEnable of BrowserFrame //
  892.  
  893. inline void BrowserFrame::MenuItemEnable(int item)
  894. {
  895.     HMENU hMenu;            /* Menu handle */
  896.  
  897.     // Get the menu handle
  898.  
  899.     hMenu = GetMenu(HWindow);
  900.  
  901.     // Enable menu item.
  902.  
  903.     EnableMenuItem(hMenu,item,MF_ENABLED);
  904. }
  905.  
  906. // Summary -----------------------------------------------------------------
  907. //
  908. //    Disables selected menu item.
  909. //
  910. // Parameter
  911. //
  912. //    item.  Is the menu item number to disable.
  913. //
  914. // End ---------------------------------------------------------------------
  915.  
  916. // member GetWindowClass of BrowserFrame //
  917.  
  918. inline void BrowserFrame::GetWindowClass(WNDCLASS& AWndClass)
  919. {
  920.     TWindow::GetWindowClass(AWndClass);
  921.     MyClass = &AWndClass;
  922. }
  923.  
  924. // Summary -----------------------------------------------------------------
  925. //
  926. //    Set up windows class object.
  927. //
  928. // End ---------------------------------------------------------------------
  929.  
  930. // constructor BrowserFrame //
  931.  
  932. inline BrowserFrame::BrowserFrame(LPSTR ATitle):
  933.         TMDIFrame(ATitle,"COMMANDS")
  934. {
  935.     // Create a windows class buffer
  936.  
  937.     MyClass = new WNDCLASS;
  938.  
  939.     // Open the PXEngine for windows in single client mode
  940.  
  941.     engine = new PXI("me",PXSINGLECLIENT);
  942.     if((error = engine->RetPXError()) != PXSUCCESS)
  943.     {
  944.  
  945.         MessageBox(HWindow,engine->RetPXErrorMsg(),
  946.         "Database Error",MB_OK);
  947.         CloseWindow();
  948.     }
  949. }
  950.  
  951. // Summary -----------------------------------------------------------------
  952. //
  953. //    Create a MDI Browser frame.
  954. //
  955. // Parameters
  956. //
  957. //    Pass of the frame title and commands menu to the MDI window.
  958. //
  959. // Description
  960. //
  961. //    Initialize engine in single client mode.  If you get an error, let
  962. //    the message box say what it is and close the window.
  963. //
  964. // End ---------------------------------------------------------------------
  965.  
  966. // member CreateChild of BrowserFrame //
  967.  
  968. inline PTWindowsObject BrowserFrame::CreateChild()
  969. {
  970.     Browser *NewChild;        /* New child pointer */
  971.  
  972.     // Make a new child window
  973.  
  974.     NewChild = new Browser(this,GetChildCount()+1);
  975.  
  976.     // If the database exists, show it
  977.  
  978.     if(NewChild->RetFlag() == EXISTS){
  979.  
  980.         // Enable save menus
  981.  
  982.         MenuItemEnable(CM_FILESAVE);
  983.         MenuItemEnable(CM_FILESAVEAS);
  984.         return GetApplication()->MakeWindow(NewChild);
  985.     }
  986.     // else kill the window and return NULL
  987.  
  988.     delete NewChild;
  989.     return NULL;
  990. }
  991.  
  992. // Summary -----------------------------------------------------------------
  993. //
  994. //    Creates a new Browser window.
  995. //
  996. // Return Value
  997. //
  998. //    Returns pointer to Browser window NewChild
  999. //
  1000. // Functional Description
  1001. //
  1002. //      1.  Initialize a new child window Browser.
  1003. //
  1004. //    2.  If the new child exists, make the new window.
  1005. //
  1006. //    3.  Else kill the child and return NULL.
  1007. //
  1008. // End ---------------------------------------------------------------------
  1009.  
  1010. // destructor BrowserFrame //
  1011.  
  1012. inline BrowserFrame::~BrowserFrame()
  1013. {
  1014.     CloseChildren();
  1015.     delete engine;
  1016.     delete MyClass;
  1017. }
  1018.  
  1019. // Summary -----------------------------------------------------------------
  1020. //
  1021. //    Call CloseChildren to close any open children.  Delete the engine
  1022. //    object.
  1023. //
  1024. // End ---------------------------------------------------------------------
  1025.  
  1026. // member SetupWindow of BrowserFrame //
  1027.  
  1028. inline void BrowserFrame::SetupWindow()
  1029. {
  1030.     TMDIFrame::SetupWindow();
  1031.     Show(SW_SHOWMAXIMIZED);
  1032. }
  1033.  
  1034. // Summary -----------------------------------------------------------------
  1035. //
  1036. //    Call the MDI frame setup and set maximized show.
  1037. //
  1038. // End ---------------------------------------------------------------------
  1039.  
  1040. // member GetChildCount of BrowserFrame //
  1041.  
  1042. inline int BrowserFrame::GetChildCount()
  1043. {
  1044.     int Count = 0;
  1045.     ForEach(CountChild,&Count);
  1046.     return Count;
  1047. }
  1048.  
  1049. // Summary -----------------------------------------------------------------
  1050. //
  1051. //    Lets the Frame window count the children.
  1052. //
  1053. // End ---------------------------------------------------------------------
  1054.  
  1055. // member CreateBrowser of BrowserFrame //
  1056.  
  1057. inline void BrowserFrame::CreateBrowser(RTMessage)
  1058. {
  1059.     CreateChild();
  1060. }
  1061.  
  1062. // Summary -----------------------------------------------------------------
  1063. //
  1064. //    Creates child window when command is dispatched.
  1065. //
  1066. // End ---------------------------------------------------------------------
  1067.  
  1068. // member CheckChildren of BrowserFrame //
  1069.  
  1070. inline void BrowserFrame::CheckChildren(RTMessage)
  1071. {
  1072.     int count;            /* Number of children */
  1073.  
  1074.     count = GetChildCount();
  1075.     if(count == 1)
  1076.     {
  1077.         MenuItemDisable(CM_FILESAVE);
  1078.         MenuItemDisable(CM_FILESAVEAS);
  1079.     }
  1080. }
  1081.  
  1082. // Summary -----------------------------------------------------------------
  1083. //
  1084. //    Responds to a message sent by a Browser to check your children
  1085. //
  1086. // Parameters
  1087. //
  1088. //    RTMessage.  This is the message sent.
  1089. //
  1090. // Functional Description --------------------------------------------------
  1091. //
  1092. //    Get the child count.  If there are no children then disable the save
  1093. //    menus.
  1094. //
  1095. // End ---------------------------------------------------------------------
  1096.  
  1097. #endif